﻿#if UNITY_EDITOR
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;


public static class ScriptableObjectCreator
{
    public static void ShowDialog<T>(string defaultDestinationPath,Action<T> onScritpableObjectCreated = null)
        where T : MyScriptableObject
    {
        var selector = new ScriptableObjectSelector<T>(defaultDestinationPath, onScritpableObjectCreated);

        if (selector.SelectionTree.EnumerateTree().Count() == 1)
        {
            selector.SelectionTree.EnumerateTree().First().Select();
            selector.SelectionTree.Selection.ConfirmSelection();
        }
        else
        {

            selector.ShowInPopup(200);
        }
    }
    
    private class ScriptableObjectSelector<T> : OdinSelector<Type> where T : MyScriptableObject
    {
        private Action<T> onScritpableObjectCreated;
        private string defaultDestinationPath;

        public ScriptableObjectSelector(string defaultDestinationPath, Action<T> onScritpableObjectCreated = null)
        {
            this.onScritpableObjectCreated = onScritpableObjectCreated;
            this.defaultDestinationPath = defaultDestinationPath;
            this.SelectionConfirmed += this.ShowSaveFileDialog;
            
        }

        protected override void BuildSelectionTree(OdinMenuTree tree)
        {
            var scriptableObjectTypes = AssemblyUtilities.GetTypes(AssemblyTypeFlags.CustomTypes)
                .Where(x => x.IsClass && !x.IsAbstract && x.InheritsFrom(typeof(T)));

            tree.Selection.SupportsMultiSelect = false;
            tree.Config.DrawSearchToolbar = true;

            foreach (Type obj in scriptableObjectTypes)
            {
                if (obj!=typeof(MyScriptableObject))
                {
                    tree.Add(TypeUtils.GetZHNameByT(obj), obj);
                }
                
            }
        }

        private void ShowSaveFileDialog(IEnumerable<Type> selection)
        {
            var obj = MyScriptableObject.CreateInstance(selection.FirstOrDefault()) as T;
            var typeName= TypeUtils.GetNameByT(obj);
            string dest = this.defaultDestinationPath.TrimEnd('/');
            dest = dest + "/" + typeName;


            if (!Directory.Exists(dest))
            {
                Directory.CreateDirectory(dest);
                AssetDatabase.Refresh();
            }

            int createId = GetMaxId(obj);
            dest = EditorUtility.SaveFilePanel("Save object as", dest, typeName + createId, "asset");

            if (!string.IsNullOrEmpty(dest) && PathUtilities.TryMakeRelative(Path.GetDirectoryName(Application.dataPath), dest, out dest))
            {
                AssetDatabase.CreateAsset(obj, dest);
                AssetDatabase.Refresh();

                if (this.onScritpableObjectCreated != null)
                {
                    obj.id = GetMaxId(obj);
                    this.onScritpableObjectCreated(obj);
                }
            }
            else
            {
                UnityEngine.Object.DestroyImmediate(obj);
            }
        }

        private int GetMaxId(MyScriptableObject obj)
        {
            string path = TypeUtils.GetNameByT(obj) + "/";

            List<string> fileNames = EditerFilesManager.GetFiles(MyAssetsConfig.skillAssetsPath + path);

            int id = 0;
            for (int i = 0; i < fileNames.Count; i++)
            {
                T item = AssetDatabase.LoadAssetAtPath<T>(MyAssetsConfig.skillAssetsPath + path + fileNames[i]);
                if (item.id > id)
                {
                    id = item.id;
                }
            }
            id = id + 1;
            return id;
        }
    }
}
#endif